//
// CXInputPin.cpp
//

#include <streams.h>
#include <dvdmedia.h>
#include "CFilterNetSender.h"
#include "CXInputPin.h"
#include "stdio.h"

/////////////////////////////////////////////////////////////////////////////////////////
CXInputPin::CXInputPin(CFilterNetSender *pFilter, HRESULT *phr) :
CRenderedInputPin(NAME("Input Pin"), pFilter, &pFilter->mFilterLock, phr, L"Input")
{
	mFilter      = pFilter;
	mSocket		 = INVALID_SOCKET;
	mIsMediaTypeSent = FALSE;
}

CXInputPin::~CXInputPin()
{
	if (mSocket != INVALID_SOCKET)
	{
		closesocket(mSocket);
		mSocket = INVALID_SOCKET;
	}
}

STDMETHODIMP CXInputPin::Receive(IMediaSample *pSample)
{
	CAutoLock  lck(&mReceiveLock);
	HRESULT hr = CRenderedInputPin::Receive(pSample);

	if (SUCCEEDED(hr))
	{
		if (m_SampleProps.dwStreamId == AM_STREAM_MEDIA) 
		{
			PBYTE pData;
			pSample->GetPointer(&pData);
			long length = pSample->GetActualDataLength();
			int  bytes  = 0;

			// Send this sample
			if (mSocket != INVALID_SOCKET)
			{
				// Send a media type first. Send once!
				if (!mIsMediaTypeSent)
				{
					mIsMediaTypeSent = TRUE;
					bytes = SendMediaType();
				}

				// Send header
				mPackHeader.pack_type = PT_Payload;
				mPackHeader.pack_size = length;
				mPackHeader.my_hton();
				bytes = send(mSocket, (char*)&mPackHeader, sizeof(mPackHeader), 0);
				// Send payload
				bytes = send(mSocket, (char*)pData, length, 0);
			}
		}
	}
	
	return hr;
}

int CXInputPin::SendMediaType(void)
{
	int bytes = 0;
	if (mSocket != INVALID_SOCKET)
	{
		// Determine media type: audio ? video ?
		if (m_mt.formattype == FORMAT_VideoInfo)
		{
			mPackHeader.pack_type = PT_VideoMediaType;
		}
		else
		{
			mPackHeader.pack_type = PT_AudioMediaType;
		}
		mPackHeader.pack_size = m_mt.cbFormat; 
		mPackHeader.my_hton();
		// Send header
		bytes = send(mSocket, (char*)&mPackHeader, sizeof(mPackHeader), 0);
		// Send payload
		bytes = send(mSocket, (char *)m_mt.pbFormat, m_mt.cbFormat, 0);
	}
	return bytes;
}

STDMETHODIMP CXInputPin::EndOfStream(void)
{
	CAutoLock  lck(&mReceiveLock);
//	if (mSocket != INVALID_SOCKET)
//	{
//		closesocket(mSocket);
//		mSocket = INVALID_SOCKET;
//	}
	
	return CRenderedInputPin::EndOfStream();
}

STDMETHODIMP CXInputPin::BeginFlush(void)
{
	CAutoLock lck(&mFilter->mFilterLock);

	HRESULT hr = CRenderedInputPin::BeginFlush();

	return hr;
}

STDMETHODIMP CXInputPin::EndFlush(void)
{
	CAutoLock lck(&mFilter->mFilterLock);

	return CRenderedInputPin::EndFlush();
}

STDMETHODIMP CXInputPin::ReceiveCanBlock(void)
{
	return S_OK;
}

HRESULT CXInputPin::CheckMediaType(const CMediaType * inMediaType)
{
	if (inMediaType->formattype == FORMAT_VideoInfo ||
		inMediaType->formattype == FORMAT_WaveFormatEx)
	{
		return S_OK;
	}
	return E_FAIL;
}

void CXInputPin::SetStreamSocket(SOCKET inSocket)
{
	mSocket = inSocket;
}

void CXInputPin::CancelPendingSend(void)
{
	if (mSocket != INVALID_SOCKET)
	{
		closesocket(mSocket);
		mSocket = INVALID_SOCKET;
	}
}